/**
 * AspectjChangeManager.java
 *
 * Created on Mar 8, 2007 at 11:29:36 PM.
 */
package org.yaorm.impl;

import java.util.Collection;
import java.util.concurrent.CopyOnWriteArrayList;

import org.yaorm.IChangeManager;
import org.yaorm.IFieldChangeEventSink;
import org.yaorm.IFieldChangeListener;

/**
 * A change manager implementation.
 * 
 * IDEAS:
 *  - changes could be dispatched in a different thread, but we must make sure they were all dispatched before
 *    dispatching Transaction Boundary events. 
 *  
 * @author <a href="mailto:alexei.guevara@objectivedesigns.ca">Alexei Guevara</a>
 * @version $Revision: 1.7 $ updated on $Date: 2006/02/06 21:33:15 $ by $Author: aguevara $
 */
public final class ChangeManager implements IChangeManager, IFieldChangeEventSink {
    
    private final Collection<IFieldChangeListener> myFieldChangeListeners;

    /**
     * Singleton AspectjChangeManager. There will always be one Aspectj change manager per JVM. 
     */
    public static final ChangeManager INSTANCE = new ChangeManager();
    
    private ChangeManager() {
        myFieldChangeListeners = new CopyOnWriteArrayList<IFieldChangeListener>();
    }

    /**
     * {@inheritDoc}
     */
    public void subscribe(IFieldChangeListener theListener) {
        myFieldChangeListeners.add( theListener );
        
    }

    /**
     * {@inheritDoc}
     */
    public void notifyFieldChange(Object theInstance, String theFieldName, Object theFieldValue) {
        for ( IFieldChangeListener listener : myFieldChangeListeners ) {
            listener.changed(theInstance, theFieldName, theFieldValue);
        }
    }

}
